import {
  render,
  screen,
  fireEvent,
  waitFor,
  cleanup,
} from "@testing-library/react";
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import QuestionDetailClient from "./question-detail-client";
import { useCattellQuestionsQuery } from "@/hooks/marriage/use-cattell";
import { useGlasserQuestionsQuery } from "@/hooks/marriage/use-glasser";
import { useMarriageProfileQuery } from "@/hooks/marriage/use-profile-main";
import {
  useFormOverviewQuery,
  useFormSectionQuery,
} from "@/hooks/marriage/use-form-schema";
import {
  convertOverviewToFrontendItems,
  mapBackendSectionToFrontend,
} from "@/lib/schema-adapter";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

vi.mock("next/navigation", () => ({
  useRouter: vi.fn(() => ({ replace: vi.fn(), push: vi.fn() })),
}));

vi.mock("@/translations/provider", () => ({
  useI18n: vi.fn(() => ({
    locale: "en",
    dictionary: new Proxy({}, { get: (_, key) => key }),
  })),
}));

vi.mock("@/hooks/marriage/use-cattell", () => ({
  useCattellQuestionsQuery: vi.fn(),
  useSubmitCattellAssessmentMutation: vi.fn(() => ({ mutateAsync: vi.fn() })),
}));

vi.mock("@/hooks/marriage/use-glasser", () => ({
  useGlasserQuestionsQuery: vi.fn(),
  useSubmitGlasserAssessmentMutation: vi.fn(() => ({ mutateAsync: vi.fn() })),
}));

vi.mock("@/hooks/marriage/use-profile-main", () => ({
  useMarriageProfileQuery: vi.fn(),
}));

vi.mock("@/hooks/marriage/use-form-schema", () => ({
  useFormOverviewQuery: vi.fn(),
  useFormSectionQuery: vi.fn(),
}));

vi.mock("@/hooks/marriage/use-habcoin-payment", () => ({
  useHabcoinPaymentMutation: vi.fn(() => ({ mutateAsync: vi.fn() })),
}));

vi.mock("@/lib/schema-adapter", () => ({
  convertOverviewToFrontendItems: vi.fn(),
  mapBackendSectionToFrontend: vi.fn(),
}));

describe("QuestionDetailClient Validation", () => {
  const mockCattellRefetch = vi.fn();
  const mockGlasserRefetch = vi.fn();

  afterEach(() => {
    cleanup();
  });

  beforeEach(() => {
    vi.clearAllMocks();

    (useMarriageProfileQuery as any).mockReturnValue({
      data: { age: 30, gender: "male" },
      isLoading: false,
    });

    (useFormOverviewQuery as any).mockReturnValue({
      data: {},
      isLoading: false,
    });
    (useFormSectionQuery as any).mockReturnValue({
      data: undefined,
      isLoading: false,
    });
  });

  const setupTest = (slug: string, cattellData: any, glasserData: any) => {
    // Mock schema adapter to return an item for the requested slug
    (convertOverviewToFrontendItems as any).mockReturnValue([
      {
        slug: slug,
        title: "Test",
        questions: [],
      },
    ]);

    (useCattellQuestionsQuery as any).mockReturnValue({
      data: cattellData,
      isLoading: false,
      isError: false,
      refetch: mockCattellRefetch,
    });

    (useGlasserQuestionsQuery as any).mockReturnValue({
      data: glasserData,
      isLoading: false,
      isError: false,
      refetch: mockGlasserRefetch,
    });

    const queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          retry: false,
        },
      },
    });

    render(
      <QueryClientProvider client={queryClient}>
        <QuestionDetailClient
          closeLabel="Close"
          continueLabel="Continue"
          description="Desc"
          informationLabel="Info"
          itemSlug={slug}
          questionsListHref="/questions-list"
          title="Test"
        />
      </QueryClientProvider>,
    );

    // Intro screen might render first; if Start is available, click it to mount questions flow
    const startButton = screen.queryByText("Start");
    if (startButton) {
      fireEvent.click(startButton);
    }
  };

  it("should render correctly when Cattell API data is completely valid", () => {
    setupTest(
      "personality_test",
      {
        questions: [
          {
            question_number: 1,
            text: "Valid Question Cattell",
            options: [
              { id: "opt_a", label: "Opt1", value: "A" },
              { id: "opt_b", label: "Opt2", value: "B" },
              { id: "opt_c", label: "Opt3", value: "C" },
            ],
          },
        ],
      },
      null,
    );

    // Retry UI should NOT be present
    expect(screen.queryByText("Retry")).toBeNull();
    // Question text should be visible
    expect(screen.getByText("Valid Question Cattell")).toBeDefined();
  });

  it("should render Retry UI when Cattell API data is empty", () => {
    setupTest("personality_test", { questions: [] }, null);

    expect(
      screen.getAllByText("No questions found for this test."),
    ).toBeDefined();
    expect(screen.getAllByText("Retry")).toBeDefined();
  });

  it("should render Retry UI when Cattell options are invalid (schema failure) and trigger refetch on Retry", async () => {
    setupTest(
      "personality_test",
      {
        questions: [
          {
            question_number: 1,
            text: "Invalid Question",
            options: [{ label: "Opt1", value: "A" }], // Invalid schema
          },
        ],
      },
      null,
    );

    expect(
      screen.getAllByText("No questions found for this test."),
    ).toBeDefined();
    const retryBtn = screen.getAllByText("Retry")[0];

    fireEvent.click(retryBtn);
    await waitFor(() => {
      expect(mockCattellRefetch).toHaveBeenCalled();
    });
  });

  it("should render correctly when Glasser API data is completely valid", () => {
    setupTest("glasser_5_needs_test", null, {
      questions: [
        {
          question_number: 1,
          text: "Valid Question Glasser",
          factor_code: "SUR",
          options: [
            { id: "o1", label: "O1", value: 1 },
            { id: "o2", label: "O2", value: 2 },
            { id: "o3", label: "O3", value: 3 },
            { id: "o4", label: "O4", value: 4 },
            { id: "o5", label: "O5", value: 5 },
          ],
        },
      ],
    });

    expect(screen.queryByText("Retry")).toBeNull();
    expect(screen.getByText("Valid Question Glasser")).toBeDefined();
  });

  it("should render Retry UI when Glasser options are invalid (schema failure) and trigger refetch on Retry", async () => {
    setupTest("glasser_5_needs_test", null, {
      questions: [
        {
          question_number: 1,
          text: "Invalid Question Glasser",
          factor_code: "SUR",
          options: [
            { label: "O1", value: 1 },
            { label: "O2", value: 2 },
            { label: "O3", value: 3 },
            { label: "O4", value: 4 },
          ],
        },
      ],
    });
    expect(
      screen.getAllByText("No questions found for this test."),
    ).toBeDefined();
    const retryBtn = screen.getAllByText("Retry")[0];

    fireEvent.click(retryBtn);
    await waitFor(() => {
      expect(mockGlasserRefetch).toHaveBeenCalled();
    });
  });

  it("should render profile questions using ID-based data flow", () => {
    const profileItem = {
      slug: "profile_test",
      title: "Profile Form",
      questions: [
        {
          id: "q_123",
          title: "Dynamic ID Question",
          type: "text",
          order: 1,
          required: true,
          isVisible: true,
          private: false,
          description: "",
          tooltip: "",
          extras: {},
          options: [],
        },
        {
          id: "q_456",
          title: "Another ID Question",
          type: "radio",
          order: 2,
          required: false,
          isVisible: true,
          private: false,
          description: "",
          tooltip: "",
          extras: {},
          options: [
            { id: "opt_1", label: "Yes", value: "yes", order: 1 },
            { id: "opt_2", label: "No", value: "no", order: 2 },
          ],
        },
      ],
    };
    (convertOverviewToFrontendItems as any).mockReturnValue([
      {
        slug: "profile_test",
        title: "Profile Form",
        questions: [],
      },
    ]);
    (useFormSectionQuery as any).mockReturnValue({
      data: {
        section: { cards: [] },
        answers: {},
        section_progress: { completion_percent: 0 },
      },
      isLoading: false,
    });
    (mapBackendSectionToFrontend as any).mockReturnValue(profileItem);

    const queryClient = new QueryClient({
      defaultOptions: { queries: { retry: false } },
    });

    render(
      <QueryClientProvider client={queryClient}>
        <QuestionDetailClient
          closeLabel="Close"
          continueLabel="Continue"
          description="Desc"
          informationLabel="Info"
          itemSlug="profile_test"
          questionsListHref="/questions-list"
          title="Profile Test"
        />
      </QueryClientProvider>,
    );

    // Profile questions render directly, no start button
    expect(screen.getByText(/Dynamic ID/)).toBeDefined();
  });

  it("renders a stable profile loading shell while section data is cold", () => {
    (convertOverviewToFrontendItems as any).mockReturnValue([
      {
        slug: "profile_test",
        title: "Overview Profile Title",
        questions: [],
      },
    ]);
    (useFormSectionQuery as any).mockReturnValue({
      data: undefined,
      isLoading: true,
    });
    (useCattellQuestionsQuery as any).mockReturnValue({
      data: undefined,
      isLoading: false,
    });
    (useGlasserQuestionsQuery as any).mockReturnValue({
      data: undefined,
      isLoading: false,
    });

    const queryClient = new QueryClient({
      defaultOptions: { queries: { retry: false } },
    });

    render(
      <QueryClientProvider client={queryClient}>
        <QuestionDetailClient
          closeLabel="Close"
          continueLabel="Continue"
          description="Desc"
          informationLabel="Info"
          itemSlug="profile_test"
          questionsListHref="/questions-list"
          title="Route Fallback Title"
        />
      </QueryClientProvider>,
    );

    expect(screen.getByText("Overview Profile Title")).toBeDefined();
    expect(screen.getByRole("status")).toBeDefined();
    expect(screen.getByRole("button", { name: "Close" })).toBeDefined();
    expect(screen.getByRole("button", { name: "Info" })).toBeDefined();
    expect(screen.getByRole("button", { name: "Continue" })).toBeDisabled();
    expect(document.querySelector(".shimmer-bg")).toBeNull();
  });

  it("renders cached section questions while the overview refreshes", () => {
    const cachedItem = {
      slug: "profile_test",
      title: "Cached Profile Form",
      questions: [
        {
          id: "cached_question",
          title: "Cached question",
          type: "text",
          order: 1,
          required: true,
          isVisible: true,
          private: false,
          description: "",
          tooltip: "",
          extras: { placeHolder: "", range: [0, 0], options: [] },
          options: [],
        },
      ],
    };
    (convertOverviewToFrontendItems as any).mockReturnValue([]);
    (useFormOverviewQuery as any).mockReturnValue({
      data: undefined,
      isLoading: true,
    });
    (useFormSectionQuery as any).mockReturnValue({
      data: {
        section: { cards: [] },
        answers: {},
        section_progress: { completion_percent: 0 },
      },
      isLoading: false,
    });
    (mapBackendSectionToFrontend as any).mockReturnValue(cachedItem);

    const queryClient = new QueryClient({
      defaultOptions: { queries: { retry: false } },
    });
    render(
      <QueryClientProvider client={queryClient}>
        <QuestionDetailClient
          closeLabel="Close"
          continueLabel="Continue"
          description="Desc"
          informationLabel="Info"
          itemSlug="profile_test"
          questionsListHref="/questions-list"
          title="Route Fallback Title"
        />
      </QueryClientProvider>,
    );

    expect(screen.getByRole("textbox")).toBeDefined();
    expect(screen.queryByRole("status")).toBeNull();
  });

  it("uses the route title when the overview is also cold", () => {
    (convertOverviewToFrontendItems as any).mockReturnValue([]);
    (useFormOverviewQuery as any).mockReturnValue({
      data: undefined,
      isLoading: true,
    });
    (useFormSectionQuery as any).mockReturnValue({
      data: undefined,
      isLoading: true,
    });
    (useCattellQuestionsQuery as any).mockReturnValue({
      data: undefined,
      isLoading: false,
    });
    (useGlasserQuestionsQuery as any).mockReturnValue({
      data: undefined,
      isLoading: false,
    });

    const queryClient = new QueryClient({
      defaultOptions: { queries: { retry: false } },
    });

    render(
      <QueryClientProvider client={queryClient}>
        <QuestionDetailClient
          closeLabel="Close"
          continueLabel="Continue"
          description="Desc"
          informationLabel="Info"
          itemSlug="profile_test"
          questionsListHref="/questions-list"
          title="Route Fallback Title"
        />
      </QueryClientProvider>,
    );

    expect(screen.getByText("Route Fallback Title")).toBeDefined();
    expect(screen.getByRole("status")).toBeDefined();
    expect(document.querySelector(".shimmer-bg")).toBeNull();
  });
});
